home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Dev / Amiga-E / E_v3.2a / Src / Utils / Build.e next >
Text File  |  1992-09-02  |  6KB  |  248 lines

  1. /* build in E.
  2.  
  3. TODO:    - cyclic structure check
  4.     - (amigados?) constants
  5.  
  6. */
  7.  
  8. OPT OSVERSION=37
  9.  
  10. MODULE 'tools/file', 'dos/dosextens', 'dos/dos'
  11.  
  12. /* object: dep1 dep2 ....
  13.      act1
  14.      act2
  15. */
  16.  
  17. OBJECT object
  18.   next:PTR TO object
  19.   name:PTR TO CHAR
  20.   firstdep:PTR TO dependancy
  21.   firstaction:PTR TO action
  22.   child
  23. ENDOBJECT
  24.  
  25. OBJECT dependancy
  26.   next:PTR TO dependancy
  27.   object:PTR TO object
  28. ENDOBJECT
  29.  
  30. OBJECT action
  31.   next:PTR TO action
  32.   comstring:PTR TO CHAR
  33. ENDOBJECT
  34.  
  35. OBJECT arg
  36.   target,buildfile,force
  37. ENDOBJECT
  38.  
  39. DEF curline=0, curstring, uptodate=TRUE, args:PTR TO arg
  40.  
  41. PROC main() HANDLE
  42.   DEF m,l,buildfile[200]:STRING,rdargs=NIL
  43.   NEW args
  44.   IF (rdargs:=ReadArgs('TARGET,FROM/K,FORCE/S',args,NIL))=NIL THEN Raise("barg")
  45.   IF args.buildfile THEN StrCopy(buildfile,args.buildfile)
  46.   StrAdd(buildfile,'.build')
  47.   PrintF('E Build v0.8 (c) 1993 Rob and Wouter (processing "\s")\n',buildfile)
  48.   m,l:=readfile(buildfile)
  49.   buildtree(parse(stringsinfile(m,l,countstrings(m,l))))
  50.   IF uptodate THEN PrintF('All files are up to date.\n')
  51.   Raise()
  52. EXCEPT
  53.   IF rdargs THEN FreeArgs(rdargs)
  54.   IF exception=0 THEN RETURN
  55.   PrintF('Error: ')
  56.   SELECT exception
  57.     CASE "OPEN"
  58.       PrintF('couldn''t open "\s".\n',exceptioninfo)
  59.     CASE "MEM"
  60.       PrintF('not enough memory.\n')
  61.     CASE "IN"
  62.       PrintF('couldn''t read file.\n')
  63.     CASE "nobj"
  64.       PrintF('action without object.\n')
  65.     CASE "fexp"
  66.       PrintF('filename expected.\n')
  67.     CASE "dexp"
  68.       PrintF('":" expected.\n')
  69.     CASE "empt"
  70.       PrintF('nothing to build.\n')
  71.     CASE "circ"
  72.       PrintF('circular dependancies between files.\n')
  73.     CASE "bada"
  74.       PrintF('action failed to build "\s".\n',exceptioninfo)
  75.     CASE "badd"
  76.       PrintF('dependancy "\s" not available.\n',exceptioninfo)
  77.     CASE "derr"
  78.       PrintF('child process failed.\n')
  79.     CASE "ntar"
  80.       PrintF('no such target: "\s"\n',args.target)
  81.     CASE "ndep"
  82.       PrintF('no dependancies for object "\s".\n',exceptioninfo)
  83.     CASE "barg"
  84.       PrintFault(IoErr(),NIL)
  85.     DEFAULT
  86.       PrintF('burp.\n')
  87.   ENDSELECT
  88.   IF curline THEN PrintF('at line: (\d) "\s"\n',curline,curstring)
  89.   IF exception THEN PrintF('Build terminated\n')
  90.   RETURN 10
  91. ENDPROC
  92.  
  93. PROC parse(list:PTR TO LONG)
  94.   DEF l=NIL:PTR TO object, s, c, i, t
  95.   FOR curline:=0 TO ListLen(list)-1
  96.     s:=list[curline]
  97.     curstring:=s
  98.     c:=s[]
  99.     IF (c<>"#") AND (c<>"\0")            -> ignore?
  100.       IF (c=" ") OR (c="\t")            -> action
  101.         s:=eatwhite(s)
  102.         IF s[]
  103.           IF l=NIL THEN Raise("nobj")
  104.           l.firstaction:=NEW [l.firstaction,s]:action
  105.         ENDIF
  106.       ELSE                    -> object rule
  107.         i:=s
  108.         s:=eatname(s)
  109.         IF s=i THEN Raise("fexp")
  110.         t:=s
  111.         s:=eatwhite(s)
  112.         IF s[]++<>":" THEN Raise("dexp")
  113.         t[]:="\0"
  114.         l:=NEW [l,i,NIL,NIL,0]:object
  115.         s:=eatwhite(s)
  116.         IF s[]<>"\0"
  117.           REPEAT
  118.             i:=s
  119.             s:=eatname(s)
  120.             t:=s
  121.             IF t=i THEN Raise("fexp")
  122.             s:=eatwhite(s)
  123.             t[]:="\0"
  124.             l.firstdep:=NEW [l.firstdep,i]:dependancy
  125.           UNTIL s[]="\0"
  126.         ENDIF
  127.       ENDIF
  128.     ENDIF
  129.   ENDFOR
  130.   curline:=0
  131.   IF l=NIL THEN Raise("empt")
  132. ENDPROC l
  133.  
  134. PROC eatwhite(s)
  135.   WHILE (s[]=" ") OR (s[]="\t") DO s++
  136. ENDPROC s
  137.  
  138. PROC eatname(s)
  139.   WHILE (s[]<>" ") AND (s[]<>"\t") AND (s[]<>"\0") AND (s[]<>":") DO s++
  140. ENDPROC s
  141.  
  142. PROC execute(c)
  143.   PrintF('\t\s\n',c)
  144.   uptodate:=FALSE
  145.   IF Execute(c,NIL,stdout)=NIL THEN Raise("derr")
  146. ENDPROC
  147.  
  148. PROC filetime(name:PTR TO CHAR)
  149.   DEF l:PTR TO filelock, fib:fileinfoblock, date:PTR TO datestamp
  150.   IF l:=Lock(name,ACTION_READ)
  151.     IF Examine(l,fib)
  152.       date:=fib.datestamp
  153.       IF fib.direntrytype<0
  154.         UnLock(l)
  155.         RETURN date.days, Shl(date.minute,12)+date.tick
  156.       ENDIF
  157.     ENDIF
  158.     UnLock(l)
  159.   ENDIF
  160. ENDPROC -1
  161.  
  162. PROC timelater(day1,tick1,day2,tick2)
  163.   IF day1>day2
  164.     RETURN TRUE
  165.   ELSEIF day1=day2
  166.     RETURN tick1>tick2
  167.   ENDIF
  168. ENDPROC FALSE
  169.  
  170. /*----------------rob's-stuff-------------------*/
  171.  
  172. PROC buildtree(list:PTR TO object) -> returns root of tree
  173.   DEF dep:PTR TO dependancy,
  174.       obj:PTR TO object
  175.  
  176.   obj:=list
  177.   WHILE obj         -> traverse objects
  178.     dep:=obj.firstdep
  179.     WHILE dep       -> traverse dependencies
  180.       dep.object:=findobject(dep.object,list)
  181.       dep:=dep.next
  182.     ENDWHILE
  183.     obj:=obj.next
  184.   ENDWHILE
  185.  
  186.   -> CHECK CYCLES!!!
  187.  
  188.   obj:=list
  189.   IF args.target
  190.     WHILE obj
  191.       IF StrCmp(args.target,obj.name) THEN JUMP out
  192.       obj:=obj.next
  193.     ENDWHILE
  194.     Raise("ntar")
  195.     out:
  196.   ELSE
  197.     IF obj THEN WHILE obj.next DO obj:=obj.next
  198.   ENDIF
  199.   traverse(obj)
  200. ENDPROC
  201.  
  202.  
  203. -> find object in list of objects by name
  204. PROC findobject(name:PTR TO CHAR,list:PTR TO object)
  205.   WHILE list
  206.     IF StrCmp(name,list.name)
  207.       -> remove object from root list
  208.       list.child:=TRUE;
  209.       RETURN list
  210.     ENDIF
  211.     list:=list.next
  212.   ENDWHILE
  213. ENDPROC NEW [NIL,name,NIL,NIL]:object
  214.  
  215. -> child-first traversal of dependancy tree
  216. PROC traverse(obj:PTR TO object) -> executes actions in tree
  217.   DEF dep:PTR TO dependancy,maxtime1=0,maxtime2=0,time1,time2,action:PTR TO action
  218.  
  219.   IF obj.firstdep OR obj.firstaction    -> object with dependancies/actions
  220.     -> traverse children and get maximum timestamp
  221.     dep:=obj.firstdep
  222.     WHILE dep
  223.       time1,time2:=traverse(dep.object)
  224.       IF timelater(time1,time2,maxtime1,maxtime2)
  225.         maxtime1:=time1
  226.         maxtime2:=time2
  227.       ENDIF
  228.       dep:=dep.next
  229.     ENDWHILE
  230.     time1,time2:=filetime(obj.name)
  231.     IF time1<0 OR timelater(maxtime1,maxtime2,time1,time2) OR args.force
  232.       -> dependancy file(s) more recent: build object
  233.       -> execute actions
  234.       action:=obj.firstaction
  235.       WHILE action
  236.         execute(action.comstring)
  237.         action:=action.next
  238.       ENDWHILE
  239.       time1,time2:=filetime(obj.name)
  240.       IF (time1<0) AND (obj.child=TRUE) THEN Throw("bada",obj.name)
  241.     ENDIF
  242.     RETURN time1,time2
  243.   ENDIF
  244.   -> object requires no action: return timestamp
  245.   time1,time2:=filetime(obj.name);
  246.   IF time1<0 THEN Throw("badd",obj.name)
  247. ENDPROC time1,time2
  248.